x86, hvm: MMIO emulations should defer domain shutdown requests until
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 27 Mar 2008 11:39:57 +0000 (11:39 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 27 Mar 2008 11:39:57 +0000 (11:39 +0000)
the relevant instruction has been fully emulated (which may require
multiple round trips to qemu-dm).
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/arch/x86/hvm/io.c
xen/common/domain.c

index bc5f8acce33867290e7f2360f1eac6af95d3b96d..ac1e62782ae1328a7f217f5bd55b4d5962d4c1c5 100644 (file)
@@ -221,35 +221,34 @@ int handle_mmio_with_translation(unsigned long gva, unsigned long gpfn)
 
 void hvm_io_assist(void)
 {
-    struct vcpu *v = current;
-    ioreq_t *p = &get_ioreq(v)->vp_ioreq;
+    struct vcpu *curr = current;
+    ioreq_t *p = &get_ioreq(curr)->vp_ioreq;
     enum hvm_io_state io_state;
 
     if ( p->state != STATE_IORESP_READY )
     {
         gdprintk(XENLOG_ERR, "Unexpected HVM iorequest state %d.\n", p->state);
-        domain_crash(v->domain);
-        goto out;
+        domain_crash_synchronous();
     }
 
     rmb(); /* see IORESP_READY /then/ read contents of ioreq */
 
     p->state = STATE_IOREQ_NONE;
 
-    io_state = v->arch.hvm_vcpu.io_state;
-    v->arch.hvm_vcpu.io_state = HVMIO_none;
+    io_state = curr->arch.hvm_vcpu.io_state;
+    curr->arch.hvm_vcpu.io_state = HVMIO_none;
 
     if ( (io_state == HVMIO_awaiting_completion) ||
          (io_state == HVMIO_handle_mmio_awaiting_completion) )
     {
-        v->arch.hvm_vcpu.io_state = HVMIO_completed;
-        v->arch.hvm_vcpu.io_data = p->data;
+        curr->arch.hvm_vcpu.io_state = HVMIO_completed;
+        curr->arch.hvm_vcpu.io_data = p->data;
         if ( io_state == HVMIO_handle_mmio_awaiting_completion )
             (void)handle_mmio();
     }
 
- out:
-    vcpu_end_shutdown_deferral(v);
+    if ( p->state == STATE_IOREQ_NONE )
+        vcpu_end_shutdown_deferral(curr);
 }
 
 void dpci_ioport_read(uint32_t mport, ioreq_t *p)
index bc9a7d9fad36e46bcdb51ad29f30c5c650090b1d..45a9de6a9c60e45c842bf2817a322eb6f3d6e4eb 100644 (file)
@@ -393,6 +393,8 @@ void __domain_crash_synchronous(void)
         this_cpu(mc_state).flags = 0;
     }
 
+    vcpu_end_shutdown_deferral(current);
+
     for ( ; ; )
         do_softirq();
 }
@@ -459,10 +461,14 @@ void domain_resume(struct domain *d)
 
 int vcpu_start_shutdown_deferral(struct vcpu *v)
 {
+    if ( v->defer_shutdown )
+        return 1;
+
     v->defer_shutdown = 1;
     smp_mb(); /* set deferral status /then/ check for shutdown */
     if ( unlikely(v->domain->is_shutting_down) )
         vcpu_check_shutdown(v);
+
     return v->defer_shutdown;
 }